package com.umakr.ax.security.core;

import com.umakr.ax.security.service.SecurityUserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author gx
 * @since 2017/5/17
 */
public class AjaxAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    SecurityUserDetailsServiceImpl securityUserDetailsServiceImpl;

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public Authentication authenticate(Authentication authentication) {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        UserDetails userDetails = securityUserDetailsServiceImpl.loadUserByUsername(token.getName());
        if(userDetails == null) {
            throw new UsernameNotFoundException("用户不存在");
        } else if (!userDetails.isEnabled()){
            throw new DisabledException("用户已被禁用");
        } else if (!userDetails.isAccountNonExpired()) {
            throw new AccountExpiredException("账号已过期");
        } else if (!userDetails.isAccountNonLocked()) {
            throw new LockedException("账号已被锁定");
        } else if (!userDetails.isCredentialsNonExpired()) {
            throw new LockedException("凭证已过期");
        }

        // 数据库用户的密码，一般都是加密过的
        String encryptedPassword = userDetails.getPassword();

        // 用户输入的密码
        String inputPassword = (String) token.getCredentials();
        // 根据加密算法加密用户输入的密码，然后和数据库中保存的密码进行比较
        if(!passwordEncoder.matches(inputPassword, encryptedPassword)) {
            throw new BadCredentialsException("用户名/密码无效");
        }
        return new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return UsernamePasswordAuthenticationToken.class.equals(aClass);
    }
}
